<template>
  <main>
    <a-row class="header">
      <h3>Status: <span :style="{ color: connectionColor }">{{ connectionStatus }}</span></h3>
      <a-button v-if="isConnected" @click="disconnectWebSocket">Disconnect</a-button>
      <a-button v-if="!isConnected && !isConnecting" @click="connectWebSocket">Connect</a-button>
    </a-row>

    <a-row align="top" class="content" justify="space-around">
      <a-col :span="7">
        <div class="partion">
          <div>
            ACTIVE CHATS
          </div>
          <a-list
              :data-source="Object.values(connectionClient)"
              class="demo-loadmore-list"
              item-layout="horizontal"
              size="large"
          >
            <template #renderItem="{ item }">
              <a-list-item>
                <template #actions>
                  <div>
                    <a-tag v-if="item.homeStatus" color="green">
                      主页位置
                    </a-tag>
                    <a-tag v-else color="blue">
                      会话页面
                    </a-tag>
                  </div>
                  <div>
                    <a-tag v-if=" item.thinkStatus" color="blue">
                      思考模式
                    </a-tag>
                    <a-tag v-else color="red">
                      一般模式
                    </a-tag>
                  </div>
                  <div>
                    <a-tag v-if=" item.conversionStatus" color="blue">
                      正在会话
                    </a-tag>
                    <a-tag v-else color="green">
                      等待内容
                    </a-tag>
                  </div>
                </template>
                <a-list-item-meta>
                  <template #title>
                    <a>{{  item.userName }}</a>
                  </template>
                  <template #description>
                    <p>
                      {{ '会话ID:' + item.conversionId }}
                    </p>
                    <p>
                      {{ '客户端ID:' + item.socketId }}
                    </p>
                  </template>
                  <template #avatar>
                    <a-avatar :src="iconMap[item.userName ]"/>
                  </template>
                </a-list-item-meta>
              </a-list-item>
            </template>
          </a-list>
        </div>
      </a-col>
      <a-col :span="16">
        <div class="partion">
          <a-textarea
              v-model:value="message"
              :auto-size="{ minRows: 24, maxRows: 24 }" placeholder="Type a message and press Enter..." >

          </a-textarea>
          <a-divider style="height: 1px; "/>
          <a-button type="primary" @click="sendMessage('user_message')">发送</a-button>
          <a-button style="margin-left: 15px" type="primary" @click="sendMessage('operate','new_blank')">新开会话</a-button>
          <a-button style="margin-left: 15px" type="primary" @click="sendMessage('operate','select_think')">思考模式</a-button>
          <a-divider style="height: 1px; "/>
          <a-textarea
              v-model:value="message1"
              :auto-size="{ minRows: 20, maxRows: 20 }" placeholder="暂停区" >

          </a-textarea>
        </div>

      </a-col>
    </a-row>
  </main>

</template>

<script setup>
import {computed, onMounted, onUnmounted, ref} from 'vue';

const message = ref('');
const message1 = ref('');
const receivedMessages = ref([]);
const connectionClient = ref({})
const connectionStatus = ref('Disconnected');
const isConnected = ref(false);
const isConnecting = ref(false); // To prevent multiple connection attempts
let socket = null;
// 用于存放 setInterval 返回的 ID，以便后续清除
let reconnectIntervalId = ref(null);


let  iconMap  = reactive({

  "chat.deepseek.com":'http://127.0.0.1:6789/share/public/1748666983034%E7%88%B1%E4%B8%8A%E7%9A%84.svg',
  "chat.qwen.ai":'http://127.0.0.1:6789/share/public/1748667281516favicon.png',
  "grok.com":'http://127.0.0.1:6789/share/public/1748667599969favicon-light.png',
  "gemini.google.com":'http://127.0.0.1:6789/share/public/1748667562403gemini_sparkle_v002_d4735304ff6292a690345.svg'
})

const wsUrl = 'ws://localhost:3000/ws';

const connectionColor = computed(() => {
  if (isConnected.value) return 'green';
  if (connectionStatus.value === 'Error') return 'red';
  return 'orange';
});


const connectWebSocket = () => {
  if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
    console.log('WebSocket is already connected or connecting.');
    return;
  }

  isConnecting.value = true;
  connectionStatus.value = 'Connecting...';
  console.log(`Attempting to connect to ${wsUrl}`);

  socket = new WebSocket(wsUrl);

  socket.onopen = () => {
    isConnected.value = true;
    isConnecting.value = false;
    connectionStatus.value = 'Connected';
    // **核心：连接成功，清除重连定时器**
    if (reconnectIntervalId.value) {
      clearInterval(reconnectIntervalId.value);
      reconnectIntervalId.value = null;
      console.log('Reconnection timer cleared.');
    }
  };

  socket.onmessage = (event) => {
    let status = JSON.parse(event.data);


    for (const statusKey in connectionClient.value) {
      delete connectionClient.value[statusKey]
    }
    for (const clientId in status) {
      let status1 = status[clientId];
      let strings = clientId.split(':');

      let userName = strings[0]

      connectionClient.value[clientId] = {...status1, userName}
    }
  };

  socket.onerror = (error) => {
    isConnecting.value = false;
    isConnected.value = false;
    connectionStatus.value = 'Error';
    console.error('WebSocket Error: ', error);
    // Note: The 'error' event will likely be followed by a 'close' event.
  };

  socket.onclose = (event) => {
    isConnected.value = false;
    isConnecting.value = false;
    if (event.wasClean) {
      connectionStatus.value = `Disconnected (Code: ${event.code}, Reason: ${event.reason || 'No reason'})`;
      console.log(`WebSocket connection closed cleanly: Code=${event.code}, Reason=${event.reason}`);
    } else {
      // e.g. server process killed or network down
      // event.code is usually 1006 in this case
      connectionStatus.value = `Connection Died (Code: ${event.code})`;
      console.log('WebSocket connection died or was not closed cleanly.');
    }


    // **核心：连接关闭，启动5秒一次的重连定时器**
    // 确保不会重复创建定时器
    if (!reconnectIntervalId) {
      console.log('Starting reconnection timer (every 5 seconds)...');
      reconnectIntervalId = setInterval(() => {
        console.log('Attempting to reconnect via timer...');
        connectWebSocket();
      }, 5000); // 5000毫秒 = 5秒
    }
  };
};


function convertMathDelimiters (input) {

  let result = input.replace(/\$\$(.*?)\$\$/gs, '\\[$1\\]')

  result = result.replace(/\$([^\$]+?)\$/g, '\\($1\\)')

  return result
}




const sendMessage = (type,op_message) => {
  let msgToSend = ''
  if (type === 'user_message') {
    if (socket && socket.readyState === WebSocket.OPEN && message.value.trim() !== '') {
      let data = {type: 'user_message', message: message.value.trim()}
      msgToSend = JSON.stringify(data);
      socket.send(msgToSend);
      message.value = '';
    } else {
      console.log('WebSocket is not connected or message is empty.');
      if (!isConnected.value) {
        alert('Not connected to WebSocket. Please connect first.');
      }
    }
  } else if (type === 'operate') {
    let data = {type: 'operate', message:op_message}
    msgToSend = JSON.stringify(data);
    socket.send(msgToSend);
  }

};


const disconnectWebSocket = () => {
  if (socket && socket.readyState === WebSocket.OPEN) {
    console.log('Disconnecting WebSocket...');
    socket.close(1000, "User initiated disconnect"); // 1000 is a normal closure
  }
};

onMounted(() => {
  connectWebSocket(); // Automatically connect when component is mounted
});

onUnmounted(() => {
  if (socket) {
    console.log('Component unmounted. Closing WebSocket connection.');
    // Ensure a clean closure reason if not already closing/closed
    if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {
      socket.close(1000, "Component unmounted");
    }
  }
});
</script>

<style lang="less" scoped>
main {
  background: rgb(249, 250, 252);
  height: calc(100vh - 0px);
  width: 100%;

  .header {
    height: 100px;
  }

  .content {
    height: calc(100vh - 145px);
  }
}

div {
  margin-bottom: 10px;
}

input {
  margin-right: 10px;
  padding: 8px;
  width: calc(100% - 100px); /* Adjust width as needed */
}

button {
  padding: 8px 12px;
  cursor: pointer;
}

button:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

span {
  font-weight: bold;
}

/deep/ .ant-col {
  height: 100%;
}

.partion {
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .075);
  background: #fff;
  border-radius: 7px;
  height: 100%;
  border: 1px solid var(--default-border) !important;
  padding: 10px;
}
/deep/  .ant-list-item-action{
  display: flex;
  flex-direction: column;
}
</style>